package com.blyat.xsoft.gateway.restful.service.impl;

import com.blyat.xsoft.gateway.restful.entity.Authority;
import com.blyat.xsoft.gateway.restful.mapper.AuthorityMapper;
import com.blyat.xsoft.gateway.restful.service.AuthorityService;
import com.blyat.xsoft.kernel.restful.service.CrudService;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author syh
 * @date 2019/10/21
 **/
@Service
public class AuthorityServiceImpl extends CrudService<Authority, AuthorityMapper> implements AuthorityService {

    @Override
    public Flux<Authority> getAuthorityTree(String userId) {
        return Flux.fromIterable(mapper.getByUserId(userId))
                .collect(Collectors.groupingBy(Authority::getPid))
                .map(r -> buildTree(Authority.ROOT, null, r))
                .flatMapMany(Flux::fromIterable);
    }

    @Override
    public List<Authority> getByUserId(String userId) {
        return mapper.getByUserId(userId);
    }

    private List<Authority> buildTree(String pid, Set<String> ids, Map<String, List<Authority>> map) {
        return Optional.ofNullable(map.get(pid)).orElseGet(() -> new ArrayList<>()).stream()
                .filter(m -> pid.equals(m.getPid()))
                .sorted(Comparator.comparing(Authority::getSort))
                .map(x -> {
                    Authority.Meta meta = new Authority.Meta();
                    meta.setTitle(x.getName());
                    meta.setIcon(x.getIcon());
                    meta.setNoCache(x.isNoCache());
                    x.setMeta(meta);
                    x.setChildren(buildTree(x.getId(), ids, map));
                    if (ids != null) ids.add(pid);
                    return x;
                }).collect(Collectors.toList());
    }
}
